package com.javaeedev.junit;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

public class CheckIpAddressFilter implements Filter {

    private int[] network;
    private int[] mask;
    private boolean deny = true;

    public void init(FilterConfig config) throws ServletException {
        String s_network = config.getInitParameter("network");
        String s_mask = config.getInitParameter("mask");
        String s_deny = config.getInitParameter("deny");
        network = toIntArray(s_network);
        mask = toIntArray(s_mask);
        if("false".equalsIgnoreCase(s_deny))
            deny = false;
    }

    public void destroy() {}

    int[] toIntArray(String ip) {
        if(ip==null)
            throw new NullPointerException("Null address.");
        String[] ss = ip.split("\\.");
        if(ss.length!=4)
            throw new IllegalArgumentException("Bad address.");
        int[] address = new int[4];
        try {
            for(int i=0; i<4; i++) {
                address[i] = Integer.parseInt(ss[i]);
                if(address[i]<0 || address[i]>255)
                    throw new IllegalArgumentException("Bad address.");
            }
        }
        catch(NumberFormatException nfe) {
            throw new IllegalArgumentException("Bad address.");
        }
        return address;
    }

    boolean match(int[] target) {
        for(int i=0; i<4; i++) {
            if((target[i] & mask[i])!=(network[i] & mask[i]))
                return false;
        }
        return true;
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        int[] target = toIntArray(request.getRemoteAddr());
        boolean match = match(target);
        if((match && deny) || (!match && !deny))
            ((HttpServletResponse)response).sendError(HttpServletResponse.SC_FORBIDDEN);
        else
            chain.doFilter(request, response);
    }

}
